#include "device.h"
#include "key.h"
#include "manager.h"
#include "compute.h"
#include <stdlib.h>
#include <stdio.h>
#include <string.h>

void initial() {
    int rv;

    unsigned char* pucAdmPassword = "1234567812345678";
    unsigned int uiAdmPasswordLength = 16;
    char *primaryFactoryInformation = "primaryFactoryInformation";
    char *primaryFactoryDate = "2024-03-17";

    rv = FHEKmg_Restore_FactorySetting(pucAdmPassword, uiAdmPasswordLength, primaryFactoryInformation, primaryFactoryDate);

    rv = FHEKmg_Init_Device(pucAdmPassword, uiAdmPasswordLength);

    char* prokey_str = (char*)malloc(257);
    memset(prokey_str, 0, sizeof(char) * 257);
    rv = FHEKmg_Verification(pucAdmPassword, uiAdmPasswordLength);
    rv = FHEKmg_Backup_ProKey(pucAdmPassword, uiAdmPasswordLength, prokey_str);
    rv = FHEKmg_UnVerification();
    printf("%s\n", prokey_str);

    rv = FHEKmg_Verification(pucAdmPassword, uiAdmPasswordLength);
    rv = FHEKmg_Restore_ProKey(pucAdmPassword, uiAdmPasswordLength, prokey_str);
    rv = FHEKmg_UnVerification();

    rv = FHEKmg_Verification(pucAdmPassword, uiAdmPasswordLength);
    rv = FHEKmg_Create_Kekey(0);
    rv = FHEKmg_UnVerification();

    char kekey_str[33] = {0};
    rv = FHEKmg_Verification(pucAdmPassword, uiAdmPasswordLength);
    rv = FHEKmg_Backup_KeKey(0, kekey_str);
    rv = FHEKmg_UnVerification();
    printf("%s\n", kekey_str);

    rv = FHEKmg_Verification(pucAdmPassword, uiAdmPasswordLength);
    rv = FHEKmg_Restore_KeKey(0, kekey_str);
    rv = FHEKmg_UnVerification();
}


void manager_key_test()
{
    int rv;

    unsigned char* pucAdmPassword = "1234567812345678";
    unsigned int uiAdmPasswordLength = 16;
    char *primaryFactoryInformation = "primaryFactoryInformation";
    char *primaryFactoryDate = "2024-03-17";

    // rv = FHEKmg_Restore_FactorySetting(pucAdmPassword, uiAdmPasswordLength, primaryFactoryInformation, primaryFactoryDate);

    // char DeviceName[16 + 1];
    // DeviceName[16] = '\0';
	// char DeviceSerialNum[16 + 1];
    // DeviceSerialNum[16] = '\0';
	// char HardwareVersion[4 + 1];
    // HardwareVersion[4] = '\0';
	// char SoftwareVersion[4 + 1];
    // SoftwareVersion[4] = '\0';
	// char PrimaryFactoryInformation[40 + 1];
    // PrimaryFactoryInformation[40] = '\0';
	// char PrimaryFactoryDate[20 + 1];
    // PrimaryFactoryDate[20] = '\0';
    // rv = FHEKmg_Get_DeviceInfo(pucAdmPassword, uiAdmPasswordLength, DeviceName, DeviceSerialNum, HardwareVersion, SoftwareVersion, PrimaryFactoryInformation, PrimaryFactoryDate);
    // printf("%s\n", DeviceName);
    // printf("%s\n", DeviceSerialNum);
    // printf("%s\n", HardwareVersion);
    // printf("%s\n", SoftwareVersion);
    // printf("%s\n", PrimaryFactoryInformation);
    // printf("%s\n", PrimaryFactoryDate);


    // rv = FHEKmg_Init_Device(pucAdmPassword, uiAdmPasswordLength);


    // char* userFactoryInformation = "userFactoryInformation";
    // char* userFactoryDate = "2024-03-17";
    // rv = FHEKmg_Init_UserInfo(pucAdmPassword, uiAdmPasswordLength, userFactoryInformation, userFactoryDate);

    // char userFactoryInformation1[40 + 1];
    // userFactoryInformation1[40] = '\0';
    // char userFactoryDate1[20 + 1];
    // userFactoryDate1[20] = '\0';
    // rv = FHEKmg_Get_UserInfo(pucAdmPassword, uiAdmPasswordLength, userFactoryInformation1, userFactoryDate1);
    // printf("%s\n", userFactoryInformation1);
    // printf("%s\n", userFactoryDate1);
    
    // char device_keypair_str[512];
    // rv = FHEKmg_Verification(pucAdmPassword, uiAdmPasswordLength);
    // rv = FHEKmg_Backup_DeviceKeyPair(pucAdmPassword, uiAdmPasswordLength, device_keypair_str);
    // rv = FHEKmg_UnVerification();
    // printf("%s\n", device_keypair_str);

    // char device_keypair_str[] = "17CC25D4EAADA2C4CCAAE63A189EC3F2F7CE5F20BE6822749CF8B02645B32B3661389F7E7B6A7837A54FB295BDA44715BD24A518CB6198B02DDE8032161E4927DDD9AC325096F73266C6A111C1235DD62A3F4AD1419C5678832A87871D03F09C6700DB527C2F9B93AFE60A81113A9F46E1084811C6D8AFAE6B7B2DEDDFF80253F1D877F05AA81A9D15CC922776513B23CE8AE374E9BBC676DC07D43979E797567951C34ADBD6D5339366A012DED603D4DB73E08175F45E91DD8E4DF5E04407ADACD99AFE16D2804F1FA40CDB6F63AB0CD1E85B8C8CB299C9DEBCE85ECF77DE3589CAB49E57CF552EE3F847FA088B895B30ECCA2C580C89A88DB2D13BE31C60A1";
    // rv = FHEKmg_Verification(pucAdmPassword, uiAdmPasswordLength);
    // rv = FHEKmg_Restore_DeviceKeyPair(pucAdmPassword, uiAdmPasswordLength, device_keypair_str);
    // rv = FHEKmg_UnVerification();


    // char* prokey_str = (char*)malloc(256);
    // rv = FHEKmg_Verification(pucAdmPassword, uiAdmPasswordLength);
    // rv = FHEKmg_Backup_ProKey(pucAdmPassword, uiAdmPasswordLength, prokey_str);
    // rv = FHEKmg_UnVerification();
    // printf("%s\n", prokey_str);


    // char* prokey_str = "AF057B02373224D2612E9A944A03F28A00000010C2B7A0928110B8D554D90CF1803E99AB151F130899215659562F05C6C8922B667F80B5120F27E7FE0DE853FCC0648BECFCB774AE116A82E3E4F3D76370CE6EF536A01B658C5303C00E6166CEFE7C9D3744257CC477CAA2DEDC0EE0514D8D7341";
    // rv = FHEKmg_Verification(pucAdmPassword, uiAdmPasswordLength);
    // rv = FHEKmg_Restore_ProKey(pucAdmPassword, uiAdmPasswordLength, prokey_str);
    // rv = FHEKmg_UnVerification();


    // rv = FHEKmg_Verification(pucAdmPassword, uiAdmPasswordLength);
    // rv = FHEKmg_Create_Kekey(0);
    // rv = FHEKmg_UnVerification();


    // char kekey_str[32];
    // rv = FHEKmg_Verification(pucAdmPassword, uiAdmPasswordLength);
    // rv = FHEKmg_Backup_KeKey(0, kekey_str);
    // rv = FHEKmg_UnVerification();
    // printf("%s\n", kekey_str);


    // char kekey_str[] = "8EB06FB7D340F7166BDD428D165B135F";
    // rv = FHEKmg_Verification(pucAdmPassword, uiAdmPasswordLength);
    // rv = FHEKmg_Restore_KeKey(0, kekey_str);
    // rv = FHEKmg_UnVerification();


    // char sm1key_str[33] = {0};
    // rv = FHEKmg_Create_Sm1key(1);

    // rv = FHEKmg_Backup_Sm1key(1, sm1key_str);
    // printf("%s\n", sm1key_str);

    // char sm1key_str[] = "D54EAB32ED6FD5A03B0254B6F9F51EDF";
    // rv = FHEKmg_Restore_Sm1key(1, sm1key_str);

    
    // rv = FHEKmg_Create_FheAuth(0);

    // char* sm1key_auth_str = (char*)malloc(32);
    // rv = FHEKmg_Backup_FheAuth(0, sm1key_auth_str);
    // printf("%s\n", sm1key_auth_str);

    // rv = FHEKmg_Restore_FheAuth(0, sm1key_auth_str);
}

/**
 * @brief 测试用例：普通数据结构、单条数据
 * 
 */
void sm1_enc_dec()
{
#if 0
    char sm1key_str[33] = {0};

    FHEKmg_Create_Sm1key(1);
    FHEKmg_Backup_Sm1key(1, sm1key_str);
    FHEKmg_Restore_Sm1key(1, sm1key_str);

    FHEKmg_Create_Sm1key(2);
    FHEKmg_Backup_Sm1key(2, sm1key_str);
    FHEKmg_Restore_Sm1key(2, sm1key_str);

    FHEKmg_Create_Sm1key(3);
    FHEKmg_Backup_Sm1key(3, sm1key_str);
    FHEKmg_Restore_Sm1key(3, sm1key_str);
    
    FHEKmg_Create_FheAuth(1);
    FHEKmg_Backup_FheAuth(1, sm1key_str);
    FHEKmg_Restore_FheAuth(1, sm1key_str);

    FHEKmg_Create_FheAuth(2);
    FHEKmg_Backup_FheAuth(2, sm1key_str);
    FHEKmg_Restore_FheAuth(2, sm1key_str);

    FHEKmg_Create_FheAuth(3);
    FHEKmg_Backup_FheAuth(3, sm1key_str);
    FHEKmg_Restore_FheAuth(3, sm1key_str);

    
#else

#endif

    char* pFhe_Auth = (char*)malloc(33);
    memset(pFhe_Auth, 0, sizeof(char) * 33);
    FHEKmg_Backup_FheAuth(1, pFhe_Auth);
    
#if 0
    unsigned char pEncrypteddata1[17];
    int rv;

    int s32_x1 = 10;
    rv = PEncS32(s32_x1, 1, pEncrypteddata1);
    int s32_y1 = 0;
    rv = PDecS32(pEncrypteddata1, 1, pFhe_Auth, &s32_y1);
    if(s32_x1 == s32_y1) {
        printf("S32 successful\n");
    } else {
        printf("S32 failed\n");
    }
#else
    for(int i = 0; i < 10000; i++) {
// number one
#if 1
    unsigned char pEncrypteddata1[17];
    int rv;

    int s32_x1 = 10;
    rv = PEncS32(s32_x1, 1, pEncrypteddata1);
    // if(rv == 0) {
    //     printf("PEncS32 successful\n");
    // } else {
    //     printf("PEncS32 failed\n");
    // }
    int s32_y1 = 0;
    rv = PDecS32(pEncrypteddata1, 1, pFhe_Auth, &s32_y1);
    // if(rv == 0) {
    //     printf("PDecS32 successful\n");
    // } else {
    //     printf("PDecS32 failed\n");
    // }
    // printf("%d\n", s32_y1);
    if(s32_x1 == s32_y1) {
        printf("S32 successful\n");
    } else {
        printf("S32 failed\n");
    }

    // unsigned int uns32_x1 = 20;
    // PEnc32(uns32_x1, 1, pEncrypteddata1);
    // unsigned int uns32_y1 = 0;
    // PDec32(pEncrypteddata1, 1, pFhe_Auth, &uns32_y1);
    // // printf("%d\n", uns32_y1);
    // if(uns32_x1 == uns32_y1) {
    //     printf("US32 successful\n");
    // } else {
    //     printf("US32 failed\n");
    // }

    // long long s64_x1 = 100;
    // PEncS64(s64_x1, 1, pEncrypteddata1);
    // long long s64_y1 = 0;
    // PDecS64(pEncrypteddata1, 1, pFhe_Auth, &s64_y1);
    // // printf("%d\n", s64_y1);
    // if(s64_x1 == s64_y1) {
    //     printf("S64 successful\n");
    // } else {
    //     printf("S64 failed\n");
    // }

    // unsigned long long uns64_x1 = 200;
    // PEnc64(uns64_x1, 1, pEncrypteddata1);
    // unsigned long long uns64_y1 = 0;
    // PDec64(pEncrypteddata1, 1, pFhe_Auth, &uns64_y1);
    // // printf("%d\n", uns64_y1);
    // if(uns64_x1 == uns64_y1) {
    //     printf("US64 successful\n");
    // } else {
    //     printf("US64 failed\n");
    // }

    // float f32_x1 = 1.5;
    // PEncF32(f32_x1, 1, pEncrypteddata1);
    // float f32_y1 = 0;
    // PDecF32(pEncrypteddata1, 1, pFhe_Auth, &f32_y1);
    // // printf("%f\n", f32_y1);
    // if(f32_x1 == f32_y1) {
    //     printf("F32 successful\n");
    // } else {
    //     printf("F32 failed\n");
    // }

    // double f64_x1 = 1.25;
    // PEncF64(f64_x1, 1, pEncrypteddata1);
    // double f64_y1 = 0;
    // PDecF64(pEncrypteddata1, 1, pFhe_Auth, &f64_y1);
    // // printf("%f\n", f64_y1);
    // if(f64_x1 == f64_y1) {
    //     printf("D64 successful\n");
    // } else {
    //     printf("D64 failed\n");
    // }
#else 

#endif
    

// number two
#if 1
    unsigned char pEncrypteddata2[16];

    int s32_x2 = 9;
    PEncS32(s32_x2, 1, pEncrypteddata2);
    int s32_y2 = 0;
    PDecS32(pEncrypteddata2, 1, pFhe_Auth, &s32_y2);
    // printf("%d\n", s32_y2);
    if(s32_x2 == s32_y2) {
        printf("S32 successful\n");
    } else {
        printf("S32 failed\n");
    }

    // unsigned int uns32_x2 = 20;
    // PEnc32(uns32_x2, 2, pEncrypteddata2);
    // unsigned int uns32_y2 = 0;
    // PDec32(pEncrypteddata2, 2, pFhe_Auth, &uns32_y2);
    // printf("%d\n", uns32_y2);

    // long long s64_x2 = 100;
    // PEncS64(s64_x2, 2, pEncrypteddata2);
    // long long s64_y2 = 0;
    // PDecS64(pEncrypteddata2, 2, pFhe_Auth, &s64_y2);
    // printf("%d\n", s64_y2);

    // unsigned long long uns64_x2 = 200;
    // PEnc64(uns64_x2, 2, pEncrypteddata2);
    // unsigned long long uns64_y2 = 0;
    // PDec64(pEncrypteddata2, 2, pFhe_Auth, &uns64_y2);
    // printf("%d\n", uns64_y2);

    // float f32_x2 = 1.5;
    // PEncF32(f32_x2, 2, pEncrypteddata2);
    // float f32_y2 = 0;
    // PDecF32(pEncrypteddata2, 2, pFhe_Auth, &f32_y2);
    // printf("%f\n", f32_y2);

    // double f64_x2 = 3.25;
    // PEncF64(f64_x2, 2, pEncrypteddata2);
    // double f64_y2 = 0;
    // PDecF64(pEncrypteddata2, 2, pFhe_Auth, &f64_y2);
    // printf("%f\n", f64_y2);
#else

#endif


// 运算
#if 1
    unsigned char compute[16];
    int compute_result;

    PAdd(pEncrypteddata1, 1, pEncrypteddata2, 1, compute, 1);
    PDecS32(compute, 1, pFhe_Auth, &compute_result);
    // printf("add: %d\n", compute_result);
    if(compute_result == (s32_x1 + s32_x2)) {
        printf("PAdd successful\n");
    } else {
        printf("PAdd failed\n");
    }

    PSub(pEncrypteddata1, 1, pEncrypteddata2, 1, compute, 1);
    PDecS32(compute, 1, pFhe_Auth, &compute_result);
    // printf("sub: %d\n", compute_result);
    if(compute_result == (s32_x1 - s32_x2)) {
        printf("PSub successful\n");
    } else {
        printf("PSub failed\n");
    }

    PMul(pEncrypteddata1, 1, pEncrypteddata2, 1, compute, 1);
    PDecS32(compute, 1, pFhe_Auth, &compute_result);
    // printf("mul: %d\n", compute_result);
    if(compute_result == (s32_x1 * s32_x2)) {
        printf("PMul successful\n");
    } else {
        printf("PMul failed\n");
    }

    PDiv(pEncrypteddata1, 1, pEncrypteddata2, 1, compute, 1);
    PDecS32(compute, 1, pFhe_Auth, &compute_result);
    // printf("div: %d\n", compute_result);
    if(compute_result == (s32_x1 / s32_x2)) {
        printf("PDiv successful\n");
    } else {
        printf("PDiv failed\n");
    }
#else

#endif


// 比较 反密
#if 1
    unsigned char compare[16];
    int compare_result;

    PComLT(pEncrypteddata1, 1, pEncrypteddata2, 1, compare, 1);
    PDecS32(compare, 1, pFhe_Auth, &compare_result);
    // printf("lt: %d\n", compare_result);
    if(compare_result == (s32_x1 < s32_x2)) {
        printf("PComLT successful\n");
    } else {
        printf("PComLT failed\n");
    }

    PComLTE(pEncrypteddata1, 1, pEncrypteddata2, 1, compare, 1);
    PDecS32(compare, 1, pFhe_Auth, &compare_result);
    // printf("lte: %d\n", compare_result);
    if(compare_result == (s32_x1 <= s32_x2)) {
        printf("PComLTE successful\n");
    } else {
        printf("PComLTE failed\n");
    }

    PComGT(pEncrypteddata1, 1, pEncrypteddata2, 1, compare, 1);
    PDecS32(compare, 1, pFhe_Auth, &compare_result);
    // printf("gt: %d\n", compare_result);
    if(compare_result == (s32_x1 > s32_x2)) {
        printf("PComGT successful\n");
    } else {
        printf("PComGT failed\n");
    }

    PComGTE(pEncrypteddata1, 1, pEncrypteddata2, 1, compare, 1);
    PDecS32(compare, 1, pFhe_Auth, &compare_result);
    // printf("gte: %d\n", compare_result);
    if(compare_result == (s32_x1 >= s32_x2)) {
        printf("PComGTE successful\n");
    } else {
        printf("PComGTE failed\n");
    }

    PComEQ(pEncrypteddata1, 1, pEncrypteddata2, 1, compare, 1);
    PDecS32(compare, 1, pFhe_Auth, &compare_result);
    // printf("eq: %d\n", compare_result);
    if(compare_result == (s32_x1 == s32_x2)) {
        printf("PComEQ successful\n");
    } else {
        printf("PComEQ failed\n");
    }

    PComNE(pEncrypteddata1, 1, pEncrypteddata2, 1, compare, 1);
    PDecS32(compare, 1, pFhe_Auth, &compare_result);
    // printf("ne: %d\n", compare_result);
    if(compare_result == (s32_x1 != s32_x2)) {
        printf("PComNE successful\n");
    } else {
        printf("PComNE failed\n");
    }
#else

#endif


// 比较 反明  
#if 1
    int compare_plainresult;
    PComLTp(pEncrypteddata1, 1, pEncrypteddata2, 1, &compare_plainresult);
    // printf("ltp: %d\n", compare_plainresult);
    if(compare_plainresult == (s32_x1 < s32_x2)) {
        printf("PComLTp successful\n");
    } else {
        printf("PComLTp failed\n");
    }
    
    PComLTEp(pEncrypteddata1, 1, pEncrypteddata2, 1, &compare_plainresult);
    // printf("ltep: %d\n", compare_plainresult);
    if(compare_plainresult == (s32_x1 <= s32_x2)) {
        printf("PComLTEp successful\n");
    } else {
        printf("PComLTEp failed\n");
    }

    PComGTp(pEncrypteddata1, 1, pEncrypteddata2, 1, &compare_plainresult);
    // printf("gtp: %d\n", compare_plainresult);
    if(compare_plainresult == (s32_x1 > s32_x2)) {
        printf("PComGTp successful\n");
    } else {
        printf("PComGTp failed\n");
    }

    PComGTEp(pEncrypteddata1, 1, pEncrypteddata2, 1, &compare_plainresult);
    // printf("gtep: %d\n", compare_plainresult);
    if(compare_plainresult == (s32_x1 >= s32_x2)) {
        printf("PComGTEp successful\n");
    } else {
        printf("PComGTEp failed\n");
    }

    PComEQp(pEncrypteddata1, 1, pEncrypteddata2, 1, &compare_plainresult);
    // printf("eqp: %d\n", compare_plainresult);
    if(compare_plainresult == (s32_x1 == s32_x2)) {
        printf("PComEQp successful\n");
    } else {
        printf("PComEQp failed\n");
    }

    PComNEp(pEncrypteddata1, 1, pEncrypteddata2, 1, &compare_plainresult);
    // printf("nep: %d\n", compare_plainresult);
    if(compare_plainresult == (s32_x1 != s32_x2)) {
        printf("PComNEp successful\n");
    } else {
        printf("PComNEp failed\n");
    }
#else

#endif

    // 逻辑运算符
    // unsigned char logcompute[16];
    // int logcompute_result;
    // PLogAnd(pEncrypteddata1, 1, pEncrypteddata2, 2, logcompute, 3);
    // PDecS32(logcompute, 3, pFhe_Auth, &logcompute_result);
    // printf("logand: %d\n", logcompute_result);

    // PLogOr(pEncrypteddata1, 1, pEncrypteddata2, 2, logcompute, 3);
    // PDecS32(logcompute, 3, pFhe_Auth, &logcompute_result);
    // printf("logor: %d\n", logcompute_result);

    // PLogNot(pEncrypteddata1, 1, logcompute, 3);
    // PDecS32(logcompute, 3, pFhe_Auth, &logcompute_result);
    // printf("not: %d\n", logcompute_result);

// PDec
#if 0
    unsigned char pEncrypteddata1[16];
    unsigned char pPlaindata[8];
    int type = 0;
    unsigned long long data;

    int nCount = 6;
    unsigned char pEncrypteddataEx[16*nCount];
    unsigned char pPlaindataEx[8*nCount];
    unsigned char typeEx[nCount];

    int s32_x1 = 9;
    PEncS32(s32_x1, 1, pEncrypteddata1);
    memcpy(pEncrypteddataEx + 16*0, pEncrypteddata1, 16);
    PDec(pEncrypteddata1, 1, pFhe_Auth, pPlaindata, &type);
    data = (unsigned long long)pPlaindata[0] << 56 |
		(unsigned long long)pPlaindata[1] << 48 |
		(unsigned long long)pPlaindata[2] << 40 |
		(unsigned long long)pPlaindata[3] << 32 |
		(unsigned long long)pPlaindata[4] << 24 |
		(unsigned long long)pPlaindata[5] << 16 |
		(unsigned long long)pPlaindata[6] << 8 |
		(unsigned long long)pPlaindata[7];
    // printf("%d\n", *((int*)&data));
    // printf("%d\n", type);
    if(*((int*)&data) == s32_x1) {
        printf("PDec S32 successful\n");
    } else {
        printf("PDec S32 failed\n");
    }
    

    unsigned int uns32_x1 = 10;
    PEnc32(uns32_x1, 1, pEncrypteddata1);
    memcpy(pEncrypteddataEx + 16*1, pEncrypteddata1, 16);
    PDec(pEncrypteddata1, 1, pFhe_Auth, pPlaindata, &type);
    data = (unsigned long long)pPlaindata[0] << 56 |
		(unsigned long long)pPlaindata[1] << 48 |
		(unsigned long long)pPlaindata[2] << 40 |
		(unsigned long long)pPlaindata[3] << 32 |
		(unsigned long long)pPlaindata[4] << 24 |
		(unsigned long long)pPlaindata[5] << 16 |
		(unsigned long long)pPlaindata[6] << 8 |
		(unsigned long long)pPlaindata[7];
    // printf("%d\n", *((unsigned int*)&data));
    // printf("%d\n", type);
    if(*((unsigned int*)&data) == uns32_x1) {
        printf("PDec 32 successful\n");
    } else {
        printf("PDec 32 failed\n");
    }

    long long s64_x1 = 100;
    PEncS64(s64_x1, 1, pEncrypteddata1);
    memcpy(pEncrypteddataEx + 16*2, pEncrypteddata1, 16);
    PDec(pEncrypteddata1, 1, pFhe_Auth, pPlaindata, &type);
    data = (unsigned long long)pPlaindata[0] << 56 |
		(unsigned long long)pPlaindata[1] << 48 |
		(unsigned long long)pPlaindata[2] << 40 |
		(unsigned long long)pPlaindata[3] << 32 |
		(unsigned long long)pPlaindata[4] << 24 |
		(unsigned long long)pPlaindata[5] << 16 |
		(unsigned long long)pPlaindata[6] << 8 |
		(unsigned long long)pPlaindata[7];
    // printf("%d\n", *((long long*)&data));
    // printf("%d\n", type);
    if(*((long long*)&data) == s64_x1) {
        printf("PDec S64 successful\n");
    } else {
        printf("PDec S64 failed\n");
    }

    unsigned long long uns64_x1 = 101;
    PEnc64(uns64_x1, 1, pEncrypteddata1);
    memcpy(pEncrypteddataEx + 16*3, pEncrypteddata1, 16);
    PDec(pEncrypteddata1, 1, pFhe_Auth, pPlaindata, &type);
    data = (unsigned long long)pPlaindata[0] << 56 |
		(unsigned long long)pPlaindata[1] << 48 |
		(unsigned long long)pPlaindata[2] << 40 |
		(unsigned long long)pPlaindata[3] << 32 |
		(unsigned long long)pPlaindata[4] << 24 |
		(unsigned long long)pPlaindata[5] << 16 |
		(unsigned long long)pPlaindata[6] << 8 |
		(unsigned long long)pPlaindata[7];
    // printf("%d\n", *((unsigned long long*)&data));
    // printf("%d\n", type);
    if(*((unsigned long long*)&data) == uns64_x1) {
        printf("PDec 64 successful\n");
    } else {
        printf("PDec 64 failed\n");
    }

    float f32_x1 = 0.5;
    PEncF32(f32_x1, 1, pEncrypteddata1);
    memcpy(pEncrypteddataEx + 16*4, pEncrypteddata1, 16);
    PDec(pEncrypteddata1, 1, pFhe_Auth, pPlaindata, &type);
    data = (unsigned long long)pPlaindata[0] << 56 |
		(unsigned long long)pPlaindata[1] << 48 |
		(unsigned long long)pPlaindata[2] << 40 |
		(unsigned long long)pPlaindata[3] << 32 |
		(unsigned long long)pPlaindata[4] << 24 |
		(unsigned long long)pPlaindata[5] << 16 |
		(unsigned long long)pPlaindata[6] << 8 |
		(unsigned long long)pPlaindata[7];
    // printf("%f\n", *((float*)&data));
    // printf("%d\n", type);
    if(*((float*)&data) == f32_x1) {
        printf("PDec F32 successful\n");
    } else {
        printf("PDec F32 failed\n");
    }

    double d64_x1 = 10;
    PEncF64(d64_x1, 1, pEncrypteddata1);
    memcpy(pEncrypteddataEx + 16*5, pEncrypteddata1, 16);
    PDec(pEncrypteddata1, 1, pFhe_Auth, pPlaindata, &type);
    data = (unsigned long long)pPlaindata[0] << 56 |
		(unsigned long long)pPlaindata[1] << 48 |
		(unsigned long long)pPlaindata[2] << 40 |
		(unsigned long long)pPlaindata[3] << 32 |
		(unsigned long long)pPlaindata[4] << 24 |
		(unsigned long long)pPlaindata[5] << 16 |
		(unsigned long long)pPlaindata[6] << 8 |
		(unsigned long long)pPlaindata[7];
    // printf("%f\n", *((double*)&data));
    // printf("%d\n", type);
    if(*((double*)&data) == d64_x1) {
        printf("PDec F64 successful\n");
    } else {
        printf("PDec F64 failed\n");
    }

    // // PDecEx
    // unsigned long long dataEx;
    
    // int key1[nCount];
    // for(int i = 0; i < nCount; i++)
    //     key1[i] = 1;
    // PDecEx(nCount, pEncrypteddataEx, key1, pFhe_Auth, pPlaindataEx, typeEx);
    // for(int i = 0; i < nCount; i++)
    // {
    //     dataEx = (unsigned long long)pPlaindataEx[8*i + 0] << 56 |
	// 	(unsigned long long)pPlaindataEx[8*i + 1] << 48 |
	// 	(unsigned long long)pPlaindataEx[8*i + 2] << 40 |
	// 	(unsigned long long)pPlaindataEx[8*i + 3] << 32 |
	// 	(unsigned long long)pPlaindataEx[8*i + 4] << 24 |
	// 	(unsigned long long)pPlaindataEx[8*i + 5] << 16 |
	// 	(unsigned long long)pPlaindataEx[8*i + 6] << 8 |
	// 	(unsigned long long)pPlaindataEx[8*i + 7];
    //     switch (typeEx[i])
    //     {
    //     case 0:
    //         printf("%d\n", *((int*)&dataEx));
    //         break;
    //     case 1:
    //         printf("%d\n", *((unsigned int*)&dataEx));
    //         break;
    //     case 2:
    //         printf("%d\n", *((long long*)&dataEx));
    //         break;
    //     case 3:
    //         printf("%d\n", *((unsigned long long*)&dataEx));
    //         break;
    //     case 4:
    //         printf("%f\n", *((float*)&dataEx));
    //         break;
    //     case 5:
    //         printf("%f\n", *((double*)&dataEx));
    //         break;
    //     default:
    //         break;
    //     }
    //     printf("%d\n", typeEx[i]);
    // }
#else 

#endif
    
    }
#endif
}

void bignum_test()
{
#if 0
    FHEKmg_Create_Sm1key(1);
    FHEKmg_Create_Sm1key(2);
    FHEKmg_Create_Sm1key(3);
    
    FHEKmg_Create_FheAuth(1);
    FHEKmg_Create_FheAuth(2);
    FHEKmg_Create_FheAuth(3);
#else

#endif

    char* pFhe_Auth = (char*)malloc(33);
    FHEKmg_Backup_FheAuth(1, pFhe_Auth);

for(int i = 0; i < 1; i++) {
// number one
#if 1
    unsigned char pEncrypteddata1[32];
    
    char* bignum_x1 = "2.5";
    PEncBDecimal(bignum_x1, 1, pEncrypteddata1);
    char* bignum_y1 = (char*)malloc(51);
    memset(bignum_y1, 0, sizeof(bignum_y1));
    PDecBDecimal(pEncrypteddata1, 1, pFhe_Auth, bignum_y1);
    // printf("%s\n", bignum_y1);
    if(strcmp(bignum_x1, bignum_y1) == 0) {
        printf("PEncBDecimal PDecBDecimal successful\n");
    } else {
        printf("PEncBDecimal PDecBDecimal failed\n");
    }
#else 

#endif
    

// number two
#if 1
    unsigned char pEncrypteddata2[32];
    
    char* bignum_x2 = "-3.5";
    PEncBDecimal(bignum_x2, 1, pEncrypteddata2);
    char* bignum_y2 = (char*)malloc(51);
    memset(bignum_y2, 0, sizeof(bignum_y2));
    PDecBDecimal(pEncrypteddata2, 1, pFhe_Auth, bignum_y2);
    // printf("%s\n", bignum_y2);
    if(strcmp(bignum_x2, bignum_y2) == 0) {
        printf("PEncBDecimal PDecBDecimal successful\n");
    } else {
        printf("PEncBDecimal PDecBDecimal failed\n");
    }
#else 

#endif


// 四则运算
#if 1
    unsigned char compute[32];
    char* compute_result = (char*)malloc(51);

    PAddBd(pEncrypteddata1, 1, pEncrypteddata2, 1, compute, 1);
    PDecBDecimal(compute, 1, pFhe_Auth, compute_result);
    printf("%s + %s == %s\n", bignum_x1, bignum_x2, compute_result);

    PSubBd(pEncrypteddata1, 1, pEncrypteddata2, 1, compute, 1);
    PDecBDecimal(compute, 1, pFhe_Auth, compute_result);
    printf("%s - %s == %s\n", bignum_x1, bignum_x2, compute_result);

    PMulBd(pEncrypteddata1, 1, pEncrypteddata2, 1, compute, 1);
    PDecBDecimal(compute, 1, pFhe_Auth, compute_result);
    printf("%s * %s == %s\n", bignum_x1, bignum_x2, compute_result);

    PDivBd(pEncrypteddata1, 1, pEncrypteddata2, 1, compute, 1);
    PDecBDecimal(compute, 1, pFhe_Auth, compute_result);
    printf("%s / %s == %s\n", bignum_x1, bignum_x2, compute_result);
#else 

#endif


// 比较 反密   
#if 1
    unsigned char compare[16];
    int compare_result = 0;

    PComLTBd(pEncrypteddata1, 1, pEncrypteddata2, 1, compare, 1);
    PDecS32(compare, 1, pFhe_Auth, &compare_result);
    printf("%s < %s : %d\n", bignum_x1, bignum_x2, compare_result);

    PComLTEBd(pEncrypteddata1, 1, pEncrypteddata2, 1, compare, 1);
    PDecS32(compare, 1, pFhe_Auth, &compare_result);
    printf("%s <= %s : %d\n", bignum_x1, bignum_x2, compare_result);

    PComGTBd(pEncrypteddata1, 1, pEncrypteddata2, 1, compare, 1);
    PDecS32(compare, 1, pFhe_Auth, &compare_result);
    printf("%s > %s : %d\n", bignum_x1, bignum_x2, compare_result);

    PComGTEBd(pEncrypteddata1, 1, pEncrypteddata2, 1, compare, 1);
    PDecS32(compare, 1, pFhe_Auth, &compare_result);
    printf("%s >= %s : %d\n", bignum_x1, bignum_x2, compare_result);

    PComEQBd(pEncrypteddata1, 1, pEncrypteddata2, 1, compare, 1);
    PDecS32(compare, 1, pFhe_Auth, &compare_result);
    printf("%s == %s : %d\n", bignum_x1, bignum_x2, compare_result);

    PComNEBd(pEncrypteddata1, 1, pEncrypteddata2, 1, compare, 1);
    PDecS32(compare, 1, pFhe_Auth, &compare_result);
    printf("%s != %s : %d\n", bignum_x1, bignum_x2, compare_result);
#else

#endif 
    

// 比较 反明
#if 1
    int compare_plainresult = 0;

    PComLTpBd(pEncrypteddata1, 1, pEncrypteddata2, 1, &compare_plainresult);
    printf("%s < %s : %d\n", bignum_x1, bignum_x2, compare_plainresult);

    PComLTEpBd(pEncrypteddata1, 1, pEncrypteddata2, 1, &compare_plainresult);
    printf("%s <= %s : %d\n", bignum_x1, bignum_x2, compare_plainresult);

    PComGTpBd(pEncrypteddata1, 1, pEncrypteddata2, 1, &compare_plainresult);
    printf("%s > %s : %d\n", bignum_x1, bignum_x2, compare_plainresult);

    PComGTEpBd(pEncrypteddata1, 1, pEncrypteddata2, 1, &compare_plainresult);
    printf("%s >= %s : %d\n", bignum_x1, bignum_x2, compare_plainresult);

    PComEQpBd(pEncrypteddata1, 1, pEncrypteddata2, 1, &compare_plainresult);
    printf("%s == %s : %d\n", bignum_x1, bignum_x2, compare_plainresult);

    PComNEpBd(pEncrypteddata1, 1, pEncrypteddata2, 1, &compare_plainresult);
    printf("%s != %s : %d\n", bignum_x1, bignum_x2, compare_plainresult);

#else 

#endif
    }
}


void bignum_testEx()
{
#if 1
    FHEKmg_Create_Sm1key(1);
    FHEKmg_Create_Sm1key(2);
    FHEKmg_Create_Sm1key(3);
    
    FHEKmg_Create_FheAuth(1);
    FHEKmg_Create_FheAuth(2);
    FHEKmg_Create_FheAuth(3);
#else

#endif

    char* pFhe_Auth = (char*)malloc(33);
    FHEKmg_Backup_FheAuth(1, pFhe_Auth);

    int nCount = 3;

    int res;

for(int i = 0; i < 1; i++) {
// number one
#if 1
    unsigned char pEncrypteddata1[96];
    char *bignum_x1[nCount];
    unsigned int key[nCount];
    for(int i = 0; i < nCount; i++) {
        key[i] = 1;
    }
    
    bignum_x1[0] = "2.5";
    bignum_x1[1] = "3.5";
    bignum_x1[2] = "4.5";
    PEncBDecimalEx(nCount, bignum_x1, key, pEncrypteddata1);


    char* bignum_y1[nCount];
    for(int i = 0; i < nCount; i++) {
        bignum_y1[i] = (char *)malloc(sizeof(char) * 129);
        memset(bignum_y1[i], 0, sizeof(bignum_y1));
    }
    
    PDecBDecimalEx(nCount, pEncrypteddata1, key, pFhe_Auth, bignum_y1);
    res = 0;
    for(res = 0; res < nCount; res++) {
        if(strcmp(bignum_x1[res], bignum_y1[res]) != 0) {
            break;
        }
    }
    if(res == nCount) {
        printf("PEncBDecimalEx PDecBDecimalEx successful\n");
    } else {
        printf("PEncBDecimalEx PDecBDecimalEx failed\n");
    }

    // printf("%s\n", bignum_y1);
    
#else 

#endif
}

}

void str_test()
{
#if 0
    char sm1key_str[33] = {0};

    FHEKmg_Create_Sm1key(1);
    FHEKmg_Backup_Sm1key(1, sm1key_str);
    FHEKmg_Restore_Sm1key(1, sm1key_str);

    FHEKmg_Create_Sm1key(2);
    FHEKmg_Backup_Sm1key(2, sm1key_str);
    FHEKmg_Restore_Sm1key(2, sm1key_str);

    FHEKmg_Create_Sm1key(3);
    FHEKmg_Backup_Sm1key(3, sm1key_str);
    FHEKmg_Restore_Sm1key(3, sm1key_str);
    
    FHEKmg_Create_FheAuth(1);
    FHEKmg_Backup_FheAuth(1, sm1key_str);
    FHEKmg_Restore_FheAuth(1, sm1key_str);

    FHEKmg_Create_FheAuth(2);
    FHEKmg_Backup_FheAuth(2, sm1key_str);
    FHEKmg_Restore_FheAuth(2, sm1key_str);

    FHEKmg_Create_FheAuth(3);
    FHEKmg_Backup_FheAuth(3, sm1key_str);
    FHEKmg_Restore_FheAuth(3, sm1key_str);
#else

#endif

    char* pFhe_Auth = (char*)malloc(33);
    FHEKmg_Backup_FheAuth(1, pFhe_Auth);

    for(int i = 0; i < 1; i++) {
// str one
#if 1
    // char* bignum_x1 = "ABCABCABCABCABCABCABCABCABCABCABCAC";
    char* bignum_x1 = "9月9日";
    unsigned int len1 = getEncStrLenFromPlainStr(bignum_x1);
    unsigned char *pEncrypteddata1 = (unsigned char *)malloc(sizeof(unsigned char) * len1);
    PEncStr(bignum_x1, 1, pEncrypteddata1);
    char* bignum_y1 = (char*)malloc(strlen(bignum_x1) + 1);
    memset(bignum_y1, 0, strlen(bignum_x1) + 1);
    PDecStr(pEncrypteddata1, 1, pFhe_Auth, bignum_y1);
    if(strcmp(bignum_x1, bignum_y1) == 0) {
        printf("PEncStr PDecStr successful\n");
    } else {
        printf("PEncStr PDecStr failed\n");
    }
#else

#endif
    

// str two
#if 0
    char* bignum_x2 = "ABCABCABCABCABCABCABCABCABCABCABCABC";
    unsigned int len2 = getEncStrLenFromPlainStr(bignum_x2);
    unsigned char *pEncrypteddata2 = (unsigned char *)malloc(sizeof(unsigned char) * len2);
    PEncStr(bignum_x2, 1, pEncrypteddata2);
    char* bignum_y2 = (char*)malloc(strlen(bignum_x2) + 1);
    memset(bignum_y2, 0, strlen(bignum_x2) + 1);
    PDecStr(pEncrypteddata2, 1, pFhe_Auth, bignum_y2);
    if(strcmp(bignum_x2, bignum_y2) == 0) {
        printf("PEncStr PDecStr successful\n");
    } else {
        printf("PEncStr PDecStr failed\n");
    }
#else

#endif


// 比较 反明
#if 0
    int compare_plainresult = 0;

    PComStrLTp(pEncrypteddata1, 1, pEncrypteddata2, 1, &compare_plainresult);
    printf("%s < %s : %d\n", bignum_x1, bignum_x2, compare_plainresult);

    PComStrLTEp(pEncrypteddata1, 1, pEncrypteddata2, 1, &compare_plainresult);
    printf("%s <= %s : %d\n", bignum_x1, bignum_x2, compare_plainresult);
    
    PComStrGTp(pEncrypteddata1, 1, pEncrypteddata2, 1, &compare_plainresult);
    printf("%s > %s : %d\n", bignum_x1, bignum_x2, compare_plainresult);

    PComStrGTEp(pEncrypteddata1, 1, pEncrypteddata2, 1, &compare_plainresult);
    printf("%s >= %s : %d\n", bignum_x1, bignum_x2, compare_plainresult);

    PComStrEQp(pEncrypteddata1, 1, pEncrypteddata2, 1, &compare_plainresult);
    printf("%s == %s : %d\n", bignum_x1, bignum_x2, compare_plainresult);

    PComStrNEp(pEncrypteddata1, 1, pEncrypteddata2, 1, &compare_plainresult);
    printf("%s != %s : %d\n", bignum_x1, bignum_x2, compare_plainresult);

#else 

#endif

// 比较 反密
#if 0
    unsigned char compare[16];
    int compare_result = 0;

    PComStrLT(pEncrypteddata1, 1, pEncrypteddata2, 1, compare, 1);
    PDecS32(compare, 1, pFhe_Auth, &compare_result);
    // printf("lt: %d\n", compare_result);
    printf("%s < %s : %d\n", bignum_x1, bignum_x2, compare_result);

    PComStrLTE(pEncrypteddata1, 1, pEncrypteddata2, 1, compare, 1);
    PDecS32(compare, 1, pFhe_Auth, &compare_result);
    // printf("lt: %d\n", compare_result);
    printf("%s <= %s : %d\n", bignum_x1, bignum_x2, compare_result);

    PComStrGT(pEncrypteddata1, 1, pEncrypteddata2, 1, compare, 1);
    PDecS32(compare, 1, pFhe_Auth, &compare_result);
    // printf("lt: %d\n", compare_result);
    printf("%s > %s : %d\n", bignum_x1, bignum_x2, compare_result);

    PComStrGTE(pEncrypteddata1, 1, pEncrypteddata2, 1, compare, 1);
    PDecS32(compare, 1, pFhe_Auth, &compare_result);
    // printf("lt: %d\n", compare_result);
    printf("%s >= %s : %d\n", bignum_x1, bignum_x2, compare_result);

    PComStrEQ(pEncrypteddata1, 1, pEncrypteddata2, 1, compare, 1);
    PDecS32(compare, 1, pFhe_Auth, &compare_result);
    // printf("lt: %d\n", compare_result);
    printf("%s == %s : %d\n", bignum_x1, bignum_x2, compare_result);

    PComStrNE(pEncrypteddata1, 1, pEncrypteddata2, 1, compare, 1);
    PDecS32(compare, 1, pFhe_Auth, &compare_result);
    // printf("lt: %d\n", compare_result);
    printf("%s != %s : %d\n", bignum_x1, bignum_x2, compare_result);
#else 

#endif

    }
}

void fhe_enc_dec()
{

#if 1
    unsigned char pucPublicKey[2 * FHE_PUBKEY_BYTES + 1];
    memset(pucPublicKey, '\0', sizeof(unsigned char) * (2 * FHE_PUBKEY_BYTES + 1));
    unsigned char pucPrivateKey[2 * FHE_PRIKEY_BYTES + 1];
    memset(pucPrivateKey, '\0', sizeof(unsigned char) * (2 * FHE_PRIKEY_BYTES + 1));
    int rv = FHEKmg_Create_And_Backup_FheKeyPair(1, pucPublicKey, pucPrivateKey);
    printf("%s\n", pucPublicKey);
    printf("%s\n", pucPrivateKey);

    rv = FHEKmg_Backup_FhePriKey(1, pucPrivateKey);
    printf("%s\n", pucPrivateKey);

    rv = FHEKmg_Restore_FhePriKey(1, pucPrivateKey);
    rv = FHEKmg_Backup_FhePriKey(1, pucPrivateKey);
    printf("%s\n", pucPrivateKey);

    // unsigned char pucPublicKey[] = ;
    // unsigned char pucPrivateKey[] = ;

#else

#endif

    // unsigned char pEncrypteddata[FHE_CYPHER_BYTES];
    // for(unsigned int i = 0; i < 65536; i++) {
    //     NFHE_Encrypt(i, pEncrypteddata);
    //     unsigned int y = 0;
    //     NFHE_Decrypt(pEncrypteddata, &y);
    //     if(y == i) {
    //         printf("NFHE_Encrypt NFHE_Decrypt successful i: %d, y: %d\n", i, y);
    //     } else {
    //         printf("NFHE_Encrypt NFHE_Decrypt failed: i: %d, y: %d\n", i, y);
    //         break;
    //     }
    // }
}


void sm1_enc_decEX()
{
    FHEKmg_Create_Sm1key(1);
    FHEKmg_Create_Sm1key(2);
    FHEKmg_Create_Sm1key(3);
    char* pFhe_Auth = (char*)malloc(32);
    FHEKmg_Backup_FheAuth(0, pFhe_Auth);

    unsigned int nCount = 3;
    
    // number one
    unsigned char pEncrypteddata1[16*nCount];
    int key1[nCount];
    for(int i = 0; i < nCount; i++)
        key1[i] = i+1;

    int s32_x1[nCount];
    s32_x1[0] = 9;
    s32_x1[1] = 11;
    s32_x1[2] = 13;
    // for(int i = 0; i < nCount; i++)
    //     s32_x1[i] = 9 + i*2;
    PEncS32Ex(nCount, s32_x1, key1, pEncrypteddata1);
    int s32_y1[nCount];
    PDecS32Ex(nCount, pEncrypteddata1, key1, pFhe_Auth, s32_y1);
    for(int i = 0; i < nCount; i++)
        printf("%d\n", s32_y1[i]);

    // unsigned int uns32_x1[nCount];
    // for(int i = 0; i < nCount; i++)
    //     uns32_x1[i] = 10 + i*2;
    // PEnc32Ex(nCount, uns32_x1, key1, pEncrypteddata1);
    // unsigned int uns32_y1[nCount];
    // PDec32Ex(nCount, pEncrypteddata1, key1, pFhe_Auth, uns32_y1);
    // for(int i = 0; i < nCount; i++)
    //     printf("%d\n", uns32_y1[i]);

    // long long s64_x1[nCount];
    // for(int i = 0; i < nCount; i++)
    //     s64_x1[i] = 10 + i*2;
    // PEncS64Ex(nCount, s64_x1, key1, pEncrypteddata1);
    // long long s64_y1[nCount];
    // PDecS64Ex(nCount, pEncrypteddata1, key1, pFhe_Auth, s64_y1);
    // for(int i = 0; i < nCount; i++)
    //     printf("%d\n", s64_y1[i]);

    // unsigned long long uns64_x1[nCount];
    // for(int i = 0; i < nCount; i++)
    //     uns64_x1[i] = 10 + i*2;
    // PEnc64Ex(nCount, uns64_x1, key1, pEncrypteddata1);
    // unsigned long long uns64_y1[nCount];
    // PDec64Ex(nCount, pEncrypteddata1, key1, pFhe_Auth, uns64_y1);
    // for(int i = 0; i < nCount; i++)
    //     printf("%d\n", uns64_y1[i]);

    // float f32_x1[nCount];
    // for(int i = 0; i < nCount; i++)
    //     f32_x1[i] = 0.5 + i*2;
    // PEncF32Ex(nCount, f32_x1, key1, pEncrypteddata1);
    // float f32_y1[nCount];
    // PDecF32Ex(nCount, pEncrypteddata1, key1, pFhe_Auth, f32_y1);
    // for(int i = 0; i < nCount; i++)
    //     printf("%f\n", f32_y1[i]);

    // double d64_x1[nCount];
    // for(int i = 0; i < nCount; i++)
    //     d64_x1[i] = 0.25 + i*2;
    // PEncF64Ex(nCount, d64_x1, key1, pEncrypteddata1);
    // double d64_y1[nCount];
    // PDecF64Ex(nCount, pEncrypteddata1, key1, pFhe_Auth, d64_y1);
    // for(int i = 0; i < nCount; i++)
    //     printf("%f\n", d64_y1[i]);

    // number two
    unsigned char pEncrypteddata2[16*nCount];
    int key2[nCount];
    for(int i = 0; i < nCount; i++)
        key2[i] = i+1;
    
    int s32_x2[nCount];
    s32_x2[0] = 10;
    s32_x2[1] = 11;
    s32_x2[2] = 12;
    // for(int i = 0; i < nCount; i++)
    //     s32_x2[i] = 10 + i;    
    PEncS32Ex(nCount, s32_x2, key2, pEncrypteddata2);
    int s32_y2[nCount];
    PDecS32Ex(nCount, pEncrypteddata2, key2, pFhe_Auth, s32_y2);
    for(int i = 0; i < nCount; i++)
        printf("%d\n", s32_y2[i]);


    // 四则运算
    unsigned char compute[16*nCount];
    int compute_result[nCount];
    int key3[nCount];
    for(int i = 0; i < nCount; i++)
        key3[i] = i+1;

    PAddEx(nCount, pEncrypteddata1, key1, pEncrypteddata2, key2, compute, key3);
    PDecS32Ex(nCount, compute, key3, pFhe_Auth, compute_result);
    for(int i = 0; i < nCount; i++)
        printf("add: %d\n", compute_result[i]);

    PSubEx(nCount, pEncrypteddata1, key1, pEncrypteddata2, key2, compute, key3);
    PDecS32Ex(nCount, compute, key3, pFhe_Auth, compute_result);
    for(int i = 0; i < nCount; i++)
        printf("sub: %d\n", compute_result[i]);
    
    PMulEx(nCount, pEncrypteddata1, key1, pEncrypteddata2, key2, compute, key3);
    PDecS32Ex(nCount, compute, key3, pFhe_Auth, compute_result);
    for(int i = 0; i < nCount; i++)
        printf("mul: %d\n", compute_result[i]);

    PDivEx(nCount, pEncrypteddata1, key1, pEncrypteddata2, key2, compute, key3);
    PDecS32Ex(nCount, compute, key3, pFhe_Auth, compute_result);
    for(int i = 0; i < nCount; i++)
        printf("div: %d\n", compute_result[i]);

    // 比较 反明
    int compare_plainresult[nCount];

    PComLTExp(nCount, pEncrypteddata1, key1, pEncrypteddata2, key2, compare_plainresult);
    for(int i = 0; i < nCount; i++)
        printf("ltp: %d\n", compare_plainresult[i]);

    PComLTEExp(nCount, pEncrypteddata1, key1, pEncrypteddata2, key2, compare_plainresult);
    for(int i = 0; i < nCount; i++)
        printf("ltep: %d\n", compare_plainresult[i]);

    PComGTExp(nCount, pEncrypteddata1, key1, pEncrypteddata2, key2, compare_plainresult);
    for(int i = 0; i < nCount; i++)
        printf("gtp: %d\n", compare_plainresult[i]);

    PComGTEExp(nCount, pEncrypteddata1, key1, pEncrypteddata2, key2, compare_plainresult);
    for(int i = 0; i < nCount; i++)
        printf("gtep: %d\n", compare_plainresult[i]);

    PComEQExp(nCount, pEncrypteddata1, key1, pEncrypteddata2, key2, compare_plainresult);
    for(int i = 0; i < nCount; i++)
        printf("eqp: %d\n", compare_plainresult[i]);

    PComNEExp(nCount, pEncrypteddata1, key1, pEncrypteddata2, key2, compare_plainresult);
    for(int i = 0; i < nCount; i++)
        printf("nep: %d\n", compare_plainresult[i]);

    // 比较 反密
    unsigned char compare[16*nCount];
    int compare_result[nCount];

    PComLTEx(nCount, pEncrypteddata1, key1, pEncrypteddata2, key2, compare, key3);
    PDecS32Ex(nCount, compare, key3, pFhe_Auth, compare_result);
    for(int i = 0; i < nCount; i++)
        printf("lt: %d\n", compare_result[i]);
    
    
}


void sm2_enc_dec() {
    int rv;
#if 1

    // rv = FHESdf_Create_Sm2key();

    // char pucPublicKey[4 * ECCref_MAX_LEN + 1] = "98f305080f59dabe788c184ae9f25fc6c529db6c47d996b7cf049012351f0b3e2a364caf2462c98c18f7e56cbf6e9a3c3d28e76162811a62520293c3b810b0d2";
    // char pucPrivateKey[2 * ECCref_MAX_LEN + 1] = "fd4c634c8e9dd3b1c8b346c0bac48e5df59c1a1612d11246191bab30b769a077";
    // // for(int i = 0; i < 4 * ECCref_MAX_LEN + 1; i++) {
    // //     pucPublicKey[i] = 0;
    // // }
    // // for(int i = 0; i < 2 * ECCref_MAX_LEN + 1; i++) {
    // //     pucPrivateKey[i] = 0;
    // // }
    // rv = FHESdf_Restore_Sm2key(pucPublicKey, pucPrivateKey);

    // char pucPublicKey1[4 * ECCref_MAX_LEN + 1];
    // char pucPrivateKey1[2 * ECCref_MAX_LEN + 1];
    // rv = FHESdf_Backup_Sm2key(pucPublicKey1, pucPrivateKey1);
    
    // printf("%s\n", pucPublicKey1);
    // printf("%s\n", pucPrivateKey1);

    // // rv = FHESdf_Restore_Sm2key(pucPublicKey, pucPrivateKey);

    FHESdf_Create_Sm2key();
#else

#endif
    char pucEnc[1024];


    unsigned int dataLen = 8;
	char dataStr[] = "8220840907157723";
    char plainData[1024];

    rv = FHESdf_Sm2_Enc(dataStr, dataLen, pucEnc);

    rv = FHESdf_Sm2_Dec(pucEnc, dataLen, plainData);

    if(strcmp(dataStr, plainData) == 0) {
        printf("FHESdf_Sm2_Enc FHESdf_Sm2_Dec successful\n");
    } else {
        printf("FHESdf_Sm2_Enc FHESdf_Sm2_Dec failed\n");
    }
    
    char pucID[] = "31323334353637383132333435363738";
    unsigned int IdLength = strlen(pucID);
    char pucData_Sign[] = "F7889FDA6B9F91539122EA1C5A7698E0";
    unsigned int uiDataLength = strlen(pucData_Sign);

    char pucSignature[4 * ECCref_MAX_LEN + 1];

    rv = FHESdf_Sm2_Sign(pucID, IdLength, pucData_Sign, uiDataLength, pucSignature);

    rv = FHESdf_Sm2_Verify(pucID, IdLength, pucData_Sign, uiDataLength, pucSignature);
    printf("%d\n", rv);
}


int main(){
    int rv;
    
    rv = NFHE_OpenDevice();

    // initial();

    // manager_key_test();
    
    fhe_enc_dec();

    // sm1_enc_dec();

    // bignum_test();

    // str_test();
    
    // bignum_testEx();

    // sm1_enc_decEX();

    // sm2_enc_dec();

    rv = NFHE_CloseDevice();

    return 0;
}
